Home

Anatomy of a Window

 

The Presence of a Window

For the user to use an application, it must display the window that can be located on the screen. A window is primarily distinguishable from the rest of the screen by its being surrounded by borders. To create a window that has borders, add the WS_BORDER flag to the dwStyle of the CreateWindow() or the CreateWindowEx() functions. Here is an example:

CreateWindow(L"AnatWnd",
	     L"Anatomy of a Window",
	     WS_BORDER,
	     CW_USEDEFAULT,
             CW_USEDEFAULT,
	     CW_USEDEFAULT,
	     CW_USEDEFAULT,
             NULL,
             NULL,
	     hInstance,
	     NULL);

This would produce:

 

The Title Bar: The Window Icon

When a window comes up, it may start on top with a long bar called the title bar. If you want a window to be equipped with a title bar, add the WS_CAPTION flag to the dwStyle of the CreateWindow() or the CreateWindowEx() functions. 

The title bar itself is divided in three sections. On the left side, there may be a small picture we call an icon and it is primarily managed as a Windows resource, through a name. To display this icon, the window must be created with the WS_SYSMENU flag to its list of styles. Here is an example:

CreateWindow("AnatWnd",
	     "Anatomy of a Window",
	     WS_BORDER | WS_CAPTION | WS_SYSMENU,
	     CW_USEDEFAULT,
             CW_USEDEFAULT,
	     CW_USEDEFAULT,
	     CW_USEDEFAULT,
             NULL,
             NULL,
	     hInstance,
	     NULL);

This would produce:

By default, the operating system provides a simple icon named IDI_APPLICATION. To use it, you pass it to the LoadIcon() function with the hInstance argument set to NULL. Instead of LoadIcon(), Microsoft suggests you use the LoadImage() function. Its syntax is:

HANDLE LoadImage(HINSTANCE hinst,
                 LPCTSTR lpszName,
                 UINT uType,
                 int cxDesired,
                 int cyDesired,
                 UINT fuLoad);

If you want to provide your own icon, first create it, preferably in two versions. The first version, with a dimension of 32x32 pixels is used to represent an application in Large View of certain windows such as My Documents or Windows Explorer. This version must be assigned to the WNDCLASS::hIcon or the WNDCLASSEX::hIcon member variable.

A second version of the same icon has a dimension of 16x16 pixels. It is used on the top-left corner of a window. It is also used all but the Large View or Windows Explorer or My Documents windows. This version is passed as the WNDCLASSEX::hIconSm member variable. Here is an example:

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
	MSG        Msg;
	HWND       hWnd;
	WNDCLASSEX WndClsEx;

	// Create the application window
	WndClsEx.cbSize        = sizeof(WNDCLASSEX);
	WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
	WndClsEx.lpfnWndProc   = WndProcedure;
	WndClsEx.cbClsExtra    = 0;
	WndClsEx.cbWndExtra    = 0;
	WndClsEx.hIcon         = static_cast<HICON>(LoadImage(hInstance,
                                        MAKEINTRESOURCE(IDI_ANATWND),
                                        IMAGE_ICON,
					32,
                                        32,
					LR_DEFAULTSIZE));
	WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
	WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClsEx.lpszMenuName  = NULL;
	WndClsEx.lpszClassName = ClsName;
	WndClsEx.hInstance     = hInstance;
	WndClsEx.hIconSm       = static_cast<HICON>(LoadImage(hInstance,
                                       MAKEINTRESOURCE(IDI_ANATWND),
                                       IMAGE_ICON,
                                       16,
                                       16,
                                       LR_DEFAULTSIZE));

	// Register the application
	RegisterClassEx(&WndClsEx);

	. . . 

	return 0;
}

This would produce:

The Title Bar: The Window Menu

Besides representing the application or the window, the Window icon also holds a group of actions called the Window Menu:

This menu allows the user to close, move, or perform other necessary operations. By default, the items in this menu are Restore, Move, Size, Minimize, Maximize, and Close. These actions are usually enough for a regular application. If for some reason you would like to modify this menu, you can.

The items on the menu are stored in a zero-based array with the top-most item having an index of 0, the second at 1, etc. Before taking any action on the menu, you should first open a handle to the system menu. This can be done by calling the GetSystemMenu() function. Its syntax is:

HMENU GetSystemMenu(HWND hWnd, BOOL bRevert);

To remove an item from the menu, you can call the RemoveMenu() function. Its syntax is:

BOOL RemoveMenu(HMENU hMenu, UINT uPosition, UINT uFlags);

Here is an example that removes the third menu item:

//---------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT Msg,
			     WPARAM wParam, LPARAM lParam)
{
	HMENU hSysMenu;

	switch(Msg)
	{
	case WM_CREATE:
		hSysMenu = GetSystemMenu(hWnd, FALSE);
		RemoveMenu(hSysMenu, 2, MF_BYPOSITION);

		return 0;

	case WM_DESTROY:
		PostQuitMessage(WM_QUIT);
		return 0;
	}

	return DefWindowProc(hWnd, Msg, wParam, lParam);
}
//---------------------------------------------------------------------------

This would produce:

System Menu

To add an item to the menu, you can call the AppendMenu() function. Its syntax is:

BOOL AppendMenu(HMENU hMenu,
    		UINT uFlags,
    		UINT_PTR uIDNewItem,
    		LPCTSTR lpNewItem);

To insert a new menu item inside of existing ones, you can call the InsertMenu() function.

 

The Window Name

On the right side of the window icon, there is a long section that serves two main purposes. Like the system icon, the middle section of the title bar holds a menu. To access this menu, you can right-click the title bar. The menu that appears is the same as set in the window icon. If the menu of the window icon has been previously modified, it would appear as such when the title bar is right-clicked.

Another task of the main section of the title bar is to display the name of the window. As far as Windows and the user are concerned, the word or the group of words that appears in the middle of the title bar is the name of the window. In the programming world, this word or group of words is also referred to as the caption.

When you are a window using the CreateWindow() or the CreateWindowEx() functions, you can specify the caption by passing a string to the lpWindowName argument. To do this, you can provide a null-terminated string to the argument or declare a global string. Here is an example:

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX	WndClsEx;

	. . .

   	RegisterClassEx(&WndClsEx);

    	CreateWindow(ClsName, WndName,
}

 

After the main window of the application has been created, you can change its caption easily and there are at least two main ways you can do this. To change the caption of a window, you can call the SetWindowText() function. Its syntax is:

BOOL SetWindowText(HWND hWnd, LPCTSTR lpString);

Here is an example:

//---------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT Msg,
			     WPARAM wParam, LPARAM lParam)
{
	switch(Msg)
	{
	case WM_CREATE:

		SetWindowText(hWnd, "FunctionX Tutorials");

		return 0;

	case WM_DESTROY:
		PostQuitMessage(WM_QUIT);
		return 0;
	}

	return DefWindowProc(hWnd, Msg, wParam, lParam);
}
//---------------------------------------------------------------------------

Alternatively, you can send the WM_SETTEXT message using the SendMessage() function. With this message, the wParam parameter is not used. The lParam argument is a string that holds the caption.

To retrieve the current caption of the window, you can call the GetWindowText() function. Its syntax is:

int GetWindowText(HWND hWnd, LPTSTR lpString, int nMaxCount);

To perform the same operation, you can send the WM_GETTEXT message.

 

The System Menu

On the right side of the title bar, a window can display one to three buttons: Minimize or , Maximize or , Close or . The presence or absence of these buttons can be managed from various alternatives. Although they appear as buttons, they are not resources. In some cases, only the Close button displays. In some other cases, the buttons would appear in a combination of three. In this case, all of the buttons might be usable or one of the buttons might be disabled. To start, if you want a window to have any of these buttons, add the WS_SYSMENU flag to the dwStyle of the CreateWindow() or the CreateWindowEx() functions.

The Minimize Button

The Minimize button appears as or . The Minimize button cannot appear on its own, only with the Maximize and the Close buttons. To display the Minimize button, when creating the window, add the WS_MINIMIZEBOX flag to the dwStyle of the CreateWindow() or the CreateWindowEx() functions. Here is an example:

CreateWindow("AnatWnd",
	     "Anatomy of a Window",
	     WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
	     CW_USEDEFAULT,
             CW_USEDEFAULT,
	     CW_USEDEFAULT,
	     CW_USEDEFAULT,
             NULL,
             NULL,
	     hInstance,
	     NULL);

This would produce:

As seen on the above picture, when you add only the WS_MINIMIZEBOX style, a Minimize button appears with a disabled Maximize button. If the user clicks a Minimize button, the window disappears from the screen and becomes represented by a button on the taskbar. The button that represents a window on the taskbar also displays its application icon and its window name.

To minimize a window, the user can click its Minimize button, to programmatically minimize a window, you can call the ShowWindow() function. Its syntax is:

BOOL ShowWindow(HWND hWnd, int nCmdShow);

The first argument specifies the window on which you are taking the action. If you are minimizing the window, the second argument can have a value of SW_MINIMIZE. Here is an example:

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
			                  WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
    case WM_LBUTTONDOWN:
	ShowWindow(hWnd, SW_MINIMIZE);
	break;

    case WM_DESTROY:
        PostQuitMessage(WM_QUIT);
        break;
    }
    
	// Process the left-over messages
	return DefWindowProc(hWnd, Msg, wParam, lParam);
}

At anytime, to find out whether a window is minimized, you can call the IsIconic() function. Its syntax is:

BOOL IsIconic(HWND hWnd);

The argument of this function is the window whose minimized state you are checking.

The Maximize Button

The Maximize button appears as Maximize or Maximize Windows XP. Like Minimize, the Maximize button cannot appear on its own, only with the Minimize and the Close buttons. To display the Maximize button, when creating the window, add the WS_MAXIMIZEBOX flag to the dwStyle of the CreateWindow() or the CreateWindowEx() functions. Here is an example:

CreateWindow("AnatWnd",
	     "Anatomy of a Window",
	     WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX,
	     CW_USEDEFAULT,
             CW_USEDEFAULT,
	     CW_USEDEFAULT,
	     CW_USEDEFAULT,
             NULL,
             NULL,
	     hInstance,
	     NULL);

This would produce:

Anatomy of a Window: Maximize

If you add only the WS_MAXIMIZEBOX flag without WS_MINIMIZEBOX, a Maximize button appears with a disabled Minimize button. If the user clicks the Maximize button, the size of the window increases to occupy the whole screen. At this time, the window is described as being maximized. When a window is maximized, the Maximize button changes into a Restore button . If the user clicks the Restore button, the window comes back to the size it had the last time it was not maximized (most of this information may be stored in the Registry by the operating system; this means that the Registry can "remember" the location, dimensions, and maximized state even if it occurred days or months before).

While the user can maximize a window by clicking the Maximize button, to programmatically maximize a window, you can call the ShowWindow() function, passing the second argument as SW_MAXIMIZE. Here is an example:

LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
			                  WPARAM wParam, LPARAM lParam)
{
    switch(Msg)
    {
    case WM_LBUTTONDOWN:
	ShowWindow(hWnd, SW_MAXIMIZE);
	break;

    case WM_DESTROY:
        PostQuitMessage(WM_QUIT);
        break;
    }
    
	// Process the left-over messages
	return DefWindowProc(hWnd, Msg, wParam, lParam);
}

At anytime, to find out whether a window is maximized, you can call the IsZoomed() function. Its syntax is:

BOOL IsZoomed(HWND hWnd);

The argument of this function is the window whose maximized state you are checking.

 


Previous Copyright © 2003-2015, FunctionX, Inc. Next